<template>
  <div class="algo-manage">
    <a-alert
      message="算法配置说明"
      type="info"
      show-icon
      closable
      style="margin-bottom: 16px"
    >
      <template #description>
        <div>本页面用于配置智能检测算法。系统支持<strong>内置SDK算法</strong>和<strong>自定义YOLOv8算法</strong>。配置保存后需要重启设备才能生效。</div>
      </template>
    </a-alert>

    <div class="header">
      <a-space>
        <a-button type="primary" @click="handleAdd">
          <template #icon><plus-outlined /></template>
          添加算法
        </a-button>
        <a-button type="default" @click="refreshData" :loading="tableLoading">
          <template #icon><reload-outlined /></template>
          刷新
        </a-button>
      </a-space>
      <a-tag color="green">已启用: {{ enabledCount }}/{{ algorithmList.length }}</a-tag>
    </div>

    <a-table
      :dataSource="algorithmList"
      :columns="columns"
      :loading="tableLoading"
      :pagination="pagination"
      @change="handleTableChange"
      rowKey="type"
    >
      <template #bodyCell="{ column, record, index }">
        <template v-if="column.key === 'type'">
          <a-tag :color="getAlgoTypeColor(record.type)">
            {{ getAlgoTypeName(record.type) }}
          </a-tag>
        </template>
        <template v-else-if="column.key === 'category'">
          <a-badge :status="isBuiltinAlgo(record.type) ? 'processing' : 'warning'" :text="isBuiltinAlgo(record.type) ? '内置SDK' : '自定义YOLO'" />
        </template>
        <template v-else-if="column.key === 'enabled'">
          <a-switch
            v-model:checked="record.enabled"
            @change="handleToggleAlgorithm(record, index)"
            :loading="record.switchLoading"
          />
        </template>
        <template v-else-if="column.key === 'modelPath'">
          <a-tooltip :title="record.modelPath">
            <span class="model-path-text">{{ getModelFileName(record.modelPath) }}</span>
          </a-tooltip>
        </template>
        <template v-else-if="column.key === 'confidenceThreshold'">
          <a-progress
            :percent="(record.confidenceThreshold * 100).toFixed(0)"
            :stroke-color="getConfidenceColor(record.confidenceThreshold)"
            size="small"
            :format="() => `${(record.confidenceThreshold * 100).toFixed(0)}%`"
          />
        </template>
        <template v-else-if="column.key === 'inputSize'">
          <a-tag color="blue">{{ record.inputWidth }} × {{ record.inputHeight }}</a-tag>
        </template>
        <template v-else-if="column.key === 'actions'">
          <a-space>
            <a-tooltip title="编辑配置">
              <a-button type="link" size="small" @click="handleEdit(record, index)">
                <template #icon><edit-outlined /></template>
              </a-button>
            </a-tooltip>
            <a-tooltip title="删除算法">
              <a-button type="link" danger size="small" @click="handleDelete(record, index)">
                <template #icon><delete-outlined /></template>
              </a-button>
            </a-tooltip>
          </a-space>
        </template>
      </template>
    </a-table>

    <!-- 添加/编辑算法对话框 -->
    <a-modal
      v-model:visible="modalVisible"
      :title="modalTitle"
      :confirm-loading="modalLoading"
      @ok="handleModalOk"
      @cancel="handleModalCancel"
      width="700px"
    >
      <a-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        layout="vertical"
      >
        <a-divider orientation="left">基本信息</a-divider>

        <a-form-item label="算法类型" name="type" required>
          <a-select
            v-model:value="formData.type"
            :disabled="editMode"
            placeholder="请选择算法类型"
            @change="handleAlgoTypeChange"
          >
            <a-select-opt-group label="内置SDK算法">
              <a-select-option value="human_vehicle_detection">
                <a-badge status="processing" text="人脸/人形/车辆检测" />
              </a-select-option>
              <a-select-option value="face_capture">
                <a-badge status="processing" text="人脸抓拍" />
              </a-select-option>
              <a-select-option value="face_recognition">
                <a-badge status="processing" text="人脸识别" />
              </a-select-option>
              <a-select-option value="non_motor_elevator_detection">
                <a-badge status="processing" text="非机动车梯控检测" />
              </a-select-option>
            </a-select-opt-group>
            <a-select-opt-group label="自定义算法">
              <a-select-option value="yolov8_detection">
                <a-badge status="warning" text="YOLO检测" />
              </a-select-option>
            </a-select-opt-group>
          </a-select>
        </a-form-item>

        <a-form-item
          v-if="formData.type === 'yolov8_detection'"
          label="选择模型文件"
          name="modelPath"
          required
        >
          <a-select
            v-model:value="formData.modelPath"
            placeholder="请选择已上传的YOLO模型"
            :loading="loadingModels"
            show-search
            :filter-option="filterModelOption"
          >
            <a-select-option v-for="model in availableModels" :key="model.filename" :value="`/app/model/${model.filename}`">
              <div class="model-option">
                <file-outlined style="margin-right: 8px" />
                <span>{{ model.filename }}</span>
                <a-tag size="small" style="margin-left: 8px">{{ formatFileSize(model.size) }}</a-tag>
              </div>
              <div v-if="model.description" class="model-description">{{ model.description }}</div>
            </a-select-option>
          </a-select>
          <template #extra>
            <a @click="openModelManagePage">还没有模型?去上传模型 →</a>
          </template>
        </a-form-item>

        <a-form-item
          v-else
          label="模型文件路径"
          name="modelPath"
          required
        >
          <a-input v-model:value="formData.modelPath" placeholder="例如: /app/model/det_hvf_normal.bin" />
          <template #extra>内置算法的模型路径,通常无需修改</template>
        </a-form-item>

        <a-divider orientation="left">输入参数</a-divider>

        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="输入宽度" name="inputWidth" required>
              <a-input-number
                v-model:value="formData.inputWidth"
                :min="64"
                :max="4096"
                :step="32"
                style="width: 100%"
                placeholder="像素"
              />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="输入高度" name="inputHeight" required>
              <a-input-number
                v-model:value="formData.inputHeight"
                :min="64"
                :max="4096"
                :step="32"
                style="width: 100%"
                placeholder="像素"
              />
            </a-form-item>
          </a-col>
        </a-row>

        <a-form-item label="常用分辨率">
          <a-space>
            <a-button size="small" @click="setResolution(1024, 576)">1024×576 (16:9)</a-button>
            <a-button size="small" @click="setResolution(640, 640)">640×640 (1:1)</a-button>
            <a-button size="small" @click="setResolution(640, 480)">640×480 (4:3)</a-button>
          </a-space>
        </a-form-item>

        <a-divider orientation="left">检测参数</a-divider>

        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="置信度阈值" name="confidenceThreshold" required>
              <a-slider
                v-model:value="formData.confidenceThreshold"
                :min="0.1"
                :max="1.0"
                :step="0.01"
                :marks="{ 0.1: '10%', 0.5: '50%', 1.0: '100%' }"
                :tooltip-formatter="(val) => `${(val * 100).toFixed(0)}%`"
              />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="最大检测数量" name="maxDetections" required>
              <a-input-number
                v-model:value="formData.maxDetections"
                :min="1"
                :max="500"
                style="width: 100%"
                placeholder="个"
              />
            </a-form-item>
          </a-col>
        </a-row>

        <a-form-item label="算法描述" name="description">
          <a-textarea
            v-model:value="formData.description"
            placeholder="请输入算法功能描述(可选)"
            :rows="2"
            :maxlength="100"
            show-count
          />
        </a-form-item>

        <a-form-item label="启用状态" name="enabled">
          <a-switch v-model:checked="formData.enabled">
            <template #checkedChildren>启用</template>
            <template #unCheckedChildren>禁用</template>
          </a-switch>
          <span style="margin-left: 8px; color: rgba(0,0,0,0.45)">启用后将在系统启动时自动加载</span>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted, computed } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { useRouter } from 'vue-router';
import {
  EditOutlined,
  DeleteOutlined,
  PlusOutlined,
  ReloadOutlined,
  FileOutlined
} from '@ant-design/icons-vue';
import { getAlgorithmConfig, updateAlgorithmConfig } from '../../api/config';
import { getModelList } from '../../api/model';

export default defineComponent({
  name: 'AlgoManage',
  components: {
    EditOutlined,
    DeleteOutlined,
    PlusOutlined,
    ReloadOutlined,
    FileOutlined
  },
  setup() {
    const router = useRouter();

    // 状态管理
    const modalVisible = ref(false);
    const modalLoading = ref(false);
    const tableLoading = ref(false);
    const loadingModels = ref(false);
    const algorithmList = ref([]);
    const availableModels = ref([]);
    const editMode = ref(false);
    const editIndex = ref(-1);
    const formRef = ref(null);

    const pagination = ref({
      current: 1,
      pageSize: 10,
      total: 0,
      showSizeChanger: true,
      pageSizeOptions: ['10', '20', '50'],
      showTotal: (total) => `总共 ${total} 项`
    });

    // 表格列定义
    const columns = [
      {
        title: '算法类型',
        key: 'type',
        width: 180
      },
      {
        title: '分类',
        key: 'category',
        width: 120
      },
      {
        title: '模型文件',
        key: 'modelPath',
        ellipsis: true
      },
      {
        title: '输入尺寸',
        key: 'inputSize',
        width: 140
      },
      {
        title: '置信度',
        key: 'confidenceThreshold',
        width: 150
      },
      {
        title: '最大检测',
        dataIndex: 'maxDetections',
        key: 'maxDetections',
        width: 100
      },
      {
        title: '启用状态',
        key: 'enabled',
        width: 100
      },
      {
        title: '操作',
        key: 'actions',
        width: 120,
        fixed: 'right'
      }
    ];

    // 表单数据和验证规则
    const formData = ref({
      type: '',
      modelPath: '',
      inputWidth: 1024,
      inputHeight: 576,
      confidenceThreshold: 0.5,
      maxDetections: 100,
      enabled: true,
      engine: 'hisilicon_sdk',
      description: ''
    });

    const formRules = {
      type: [
        { required: true, message: '请选择算法类型', trigger: 'change' }
      ],
      modelPath: [
        { required: true, message: '请输入或选择模型文件路径', trigger: 'blur' }
      ],
      inputWidth: [
        { required: true, message: '请输入输入宽度', trigger: 'blur' }
      ],
      inputHeight: [
        { required: true, message: '请输入输入高度', trigger: 'blur' }
      ],
      confidenceThreshold: [
        { required: true, message: '请设置置信度阈值', trigger: 'blur' }
      ],
      maxDetections: [
        { required: true, message: '请输入最大检测数量', trigger: 'blur' }
      ]
    };

    // 计算属性
    const modalTitle = computed(() => {
      return editMode.value ? '编辑算法配置' : '添加算法';
    });

    const enabledCount = computed(() => {
      return algorithmList.value.filter(item => item.enabled).length;
    });

    // 辅助函数
    const isBuiltinAlgo = (type) => {
      return ['human_vehicle_detection', 'face_capture', 'face_recognition', 'non_motor_elevator_detection'].includes(type);
    };

    const getAlgoTypeName = (type) => {
      const typeMap = {
        'non_motor_elevator_detection': '非机动车梯控检测',
        'human_vehicle_detection': '人脸/人形/车辆检测',
        'face_capture': '人脸抓拍',
        'face_recognition': '人脸识别',
        'yolov8_detection': 'YOLO检测'
      };
      return typeMap[type] || type;
    };

    const getAlgoTypeColor = (type) => {
      const colorMap = {
        'human_vehicle_detection': 'blue',
        'face_capture': 'green',
        'face_recognition': 'purple',
        'non_motor_elevator_detection': 'orange',
        'yolov8_detection': 'red'
      };
      return colorMap[type] || 'default';
    };

    const getConfidenceColor = (threshold) => {
      if (threshold >= 0.7) return '#52c41a';
      if (threshold >= 0.5) return '#1890ff';
      return '#faad14';
    };

    const getModelFileName = (path) => {
      if (!path) return '-';
      return path.split('/').pop();
    };

    const formatFileSize = (bytes) => {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    };

    const filterModelOption = (input, option) => {
      return option.key.toLowerCase().includes(input.toLowerCase());
    };

    // 获取算法配置数据
    const fetchAlgorithmData = async () => {
      try {
        tableLoading.value = true;
        const response = await getAlgorithmConfig();
        algorithmList.value = response.algorithms || [];
        pagination.value.total = algorithmList.value.length;

        // 为每个算法项添加switchLoading状态
        algorithmList.value = algorithmList.value.map(item => ({
          ...item,
          switchLoading: false
        }));
      } catch (error) {
        console.error('获取算法配置失败:', error);
        message.error('获取算法配置失败: ' + (error.message || '未知错误'));
        algorithmList.value = [];
      } finally {
        tableLoading.value = false;
      }
    };

    // 获取可用模型列表
    const fetchAvailableModels = async () => {
      try {
        loadingModels.value = true;
        const response = await getModelList();
        availableModels.value = response.models || [];
      } catch (error) {
        console.error('获取模型列表失败:', error);
        message.warning('无法加载模型列表');
        availableModels.value = [];
      } finally {
        loadingModels.value = false;
      }
    };

    // 保存算法配置数据
    const saveAlgorithmData = async (showSuccessMessage = true) => {
      try {
        const configData = {
          algorithms: algorithmList.value.map(({ switchLoading, ...item }) => item)
        };
        await updateAlgorithmConfig(configData);
        if (showSuccessMessage) {
          message.success('算法配置更新成功,重启设备后生效');
        }
      } catch (error) {
        console.error('保存算法配置失败:', error);
        message.error('保存算法配置失败: ' + (error.message || '未知错误'));
        throw error;
      }
    };

    // 刷新数据
    const refreshData = () => {
      fetchAlgorithmData();
    };

    // 设置分辨率快捷按钮
    const setResolution = (width, height) => {
      formData.value.inputWidth = width;
      formData.value.inputHeight = height;
    };

    // 算法类型变更处理
    const handleAlgoTypeChange = (value) => {
      // YOLOv8算法加载模型列表
      if (value === 'yolov8_detection') {
        fetchAvailableModels();
        formData.value.modelPath = '';
      } else {
        // 内置算法设置默认模型路径
        const defaultPaths = {
          'human_vehicle_detection': '/app/model/det_hvf_normal.bin',
          'face_capture': '/app/model/face_capture.bin',
          'face_recognition': '/app/model/face_recognition.bin',
          'non_motor_elevator_detection': '/app/model/non_motor_elev.bin'
        };
        formData.value.modelPath = defaultPaths[value] || '';
      }
    };

    // 打开模型管理页面
    const openModelManagePage = () => {
      router.push('/config/intelligence/model');
    };

    // 处理添加算法
    const handleAdd = () => {
      editMode.value = false;
      editIndex.value = -1;
      formData.value = {
        type: '',
        modelPath: '',
        inputWidth: 1024,
        inputHeight: 576,
        confidenceThreshold: 0.5,
        maxDetections: 100,
        enabled: true,
        engine: 'hisilicon_sdk',
        description: ''
      };
      modalVisible.value = true;
    };

    // 处理编辑算法
    const handleEdit = (record, index) => {
      editMode.value = true;
      editIndex.value = index;
      formData.value = { ...record };

      // 如果是YOLOv8,加载模型列表
      if (record.type === 'yolov8_detection') {
        fetchAvailableModels();
      }

      modalVisible.value = true;
    };

    // 处理删除算法
    const handleDelete = (record, index) => {
      Modal.confirm({
        title: '确认删除',
        content: `确定要删除算法"${getAlgoTypeName(record.type)}"吗?`,
        okText: '确认',
        okType: 'danger',
        cancelText: '取消',
        onOk: async () => {
          try {
            algorithmList.value.splice(index, 1);
            pagination.value.total = algorithmList.value.length;
            await saveAlgorithmData();
          } catch (error) {
            // 删除失败时恢复数据
            await fetchAlgorithmData();
          }
        }
      });
    };

    // 处理算法启用/禁用切换
    const handleToggleAlgorithm = async (_, index) => {
      try {
        algorithmList.value[index].switchLoading = true;
        await saveAlgorithmData(false); // 不显示通用成功消息

        // 显示专门的启用/禁用成功消息
        const status = algorithmList.value[index].enabled ? '启用' : '禁用';
        message.success(`算法${status}成功,重启设备后生效`);
      } catch (error) {
        // 切换失败时恢复原状态
        algorithmList.value[index].enabled = !algorithmList.value[index].enabled;
      } finally {
        algorithmList.value[index].switchLoading = false;
      }
    };

    // 处理模态框确认
    const handleModalOk = async () => {
      try {
        await formRef.value.validate();
        modalLoading.value = true;

        // 检查算法名称是否重复(仅在新增时检查)
        if (!editMode.value) {
          const exists = algorithmList.value.some(item => item.type === formData.value.type);
          if (exists) {
            message.error('该算法类型已存在');
            return;
          }
        }

        const newData = {
          ...formData.value,
          switchLoading: false
        };

        if (editMode.value) {
          // 编辑模式
          algorithmList.value[editIndex.value] = newData;
        } else {
          // 添加模式
          algorithmList.value.push(newData);
        }

        pagination.value.total = algorithmList.value.length;
        await saveAlgorithmData();

        modalVisible.value = false;
      } catch (error) {
        if (error.errorFields) {
          // 表单验证错误
          return;
        }
        // 保存失败时恢复数据
        await fetchAlgorithmData();
      } finally {
        modalLoading.value = false;
      }
    };

    // 处理模态框取消
    const handleModalCancel = () => {
      modalVisible.value = false;
    };

    // 表格分页变化时触发
    const handleTableChange = (pag) => {
      pagination.value.current = pag.current;
      pagination.value.pageSize = pag.pageSize;
    };

    // 组件挂载时获取数据
    onMounted(() => {
      fetchAlgorithmData();
    });

    return {
      modalVisible,
      modalLoading,
      tableLoading,
      loadingModels,
      algorithmList,
      availableModels,
      editMode,
      editIndex,
      formRef,
      pagination,
      columns,
      formData,
      formRules,
      modalTitle,
      enabledCount,
      isBuiltinAlgo,
      getAlgoTypeName,
      getAlgoTypeColor,
      getConfidenceColor,
      getModelFileName,
      formatFileSize,
      filterModelOption,
      refreshData,
      setResolution,
      handleAlgoTypeChange,
      openModelManagePage,
      handleAdd,
      handleEdit,
      handleDelete,
      handleToggleAlgorithm,
      handleModalOk,
      handleModalCancel,
      handleTableChange
    };
  }
});
</script>

<style scoped>
.algo-manage {
  padding: 24px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.model-path-text {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 12px;
  color: rgba(0, 0, 0, 0.65);
}

.model-option {
  display: flex;
  align-items: center;
}

.model-description {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 4px;
  padding-left: 24px;
}

:deep(.ant-slider) {
  margin: 8px 0;
}

:deep(.ant-form-item-label) {
  padding: 0;
}

:deep(.ant-divider-horizontal.ant-divider-with-text-left) {
  margin: 16px 0 24px;
}

:deep(.ant-divider-inner-text) {
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
}

:deep(.ant-select-item-option-content) {
  padding: 0;
}

:deep(.ant-progress) {
  line-height: 1;
}
</style>
